[Designer("System.Web.UI.Design.WebControls.DataBoundControlDesigner, System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
public abstract class DataBoundControl : BaseDataBoundControl
{
    // Fields
    private DataSourceSelectArguments _arguments;
    private IDataSource _currentDataSource;
    private bool _currentDataSourceValid;
    private DataSourceView _currentView;
    private bool _currentViewIsFromDataSourceID;
    private bool _currentViewValid;
    private bool _ignoreDataSourceViewChanged;
    private string _itemType;
    private ModelDataSource _modelDataSource;
    private bool _pagePreLoadFired;
    private string _selectMethod;
    private const string DataBoundViewStateKey = "_!DataBound";
    private static readonly object EventCallingDataMethods = new object();
    private static readonly object EventCreatingModelDataSource = new object();

    // Events
    [WebSysDescription("DataBoundControl_CallingDataMethods"), WebCategory("Data")]
    public event CallingDataMethodsEventHandler CallingDataMethods
    {
        add
        {
            base.Events.AddHandler(EventCallingDataMethods, value);
        }
        remove
        {
            base.Events.RemoveHandler(EventCallingDataMethods, value);
            if (this._modelDataSource != null)
            {
                this._modelDataSource.CallingDataMethods -= value;
            }
        }
    }

    [WebSysDescription("DataBoundControl_OnCreatingModelDataSource"), WebCategory("Data")]
    public event CreatingModelDataSourceEventHandler CreatingModelDataSource
    {
        add
        {
            base.Events.AddHandler(EventCreatingModelDataSource, value);
        }
        remove
        {
            base.Events.RemoveHandler(EventCreatingModelDataSource, value);
        }
    }

    // Methods
    [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
    protected DataBoundControl()
    {
    }

    private DataSourceView ConnectToDataSourceView()
    {
        if (!this._currentViewValid || base.DesignMode)
        {
            if ((this._currentView != null) && this._currentViewIsFromDataSourceID)
            {
                this._currentView.DataSourceViewChanged -= new EventHandler(this.OnDataSourceViewChanged);
            }
            this.EnsureSingleDataSource();
            this._currentDataSource = this.GetDataSource();
            string dataMember = this.DataMember;
            if (this._currentDataSource == null)
            {
                this._currentDataSource = new ReadOnlyDataSource(this.DataSource, dataMember);
            }
            this._currentDataSourceValid = true;
            DataSourceView view = this._currentDataSource.GetView(dataMember);
            if (view == null)
            {
                throw new InvalidOperationException(SR.GetString("DataControl_ViewNotFound", new object[] { this.ID }));
            }
            this._currentViewIsFromDataSourceID = base.IsDataBindingAutomatic;
            this._currentView = view;
            if ((this._currentView != null) && this._currentViewIsFromDataSourceID)
            {
                this._currentView.DataSourceViewChanged += new EventHandler(this.OnDataSourceViewChanged);
            }
            this._currentViewValid = true;
        }
        return this._currentView;
    }

    protected virtual DataSourceSelectArguments CreateDataSourceSelectArguments()
    {
        return DataSourceSelectArguments.Empty;
    }

    internal void EnsureSingleDataSource()
    {
        if (!base.DesignMode)
        {
            if (this.IsUsingModelBinders)
            {
                if ((this.DataSourceID.Length != 0) || (this.DataSource != null))
                {
                    throw new InvalidOperationException(SR.GetString("DataControl_ItemType_MultipleDataSources", new object[] { this.ID }));
                }
            }
            else if ((this.DataSourceID.Length != 0) && (this.DataSource != null))
            {
                throw new InvalidOperationException(SR.GetString("DataControl_MultipleDataSources", new object[] { this.ID }));
            }
        }
    }

    protected virtual DataSourceView GetData()
    {
        return this.ConnectToDataSourceView();
    }

    protected virtual IDataSource GetDataSource()
    {
        if (!base.DesignMode && this.IsUsingModelBinders)
        {
            CreatingModelDataSourceEventArgs e = new CreatingModelDataSourceEventArgs();
            this.OnCreatingModelDataSource(e);
            if (e.ModelDataSource != null)
            {
                this.ModelDataSource = e.ModelDataSource;
            }
            this.UpdateModelDataSourceProperties(this.ModelDataSource);
            CallingDataMethodsEventHandler handler = base.Events[EventCallingDataMethods] as CallingDataMethodsEventHandler;
            if (handler != null)
            {
                this.ModelDataSource.CallingDataMethods += handler;
            }
            return this.ModelDataSource;
        }
        if ((!base.DesignMode && this._currentDataSourceValid) && (this._currentDataSource != null))
        {
            return this._currentDataSource;
        }
        IDataSource source = null;
        string dataSourceID = this.DataSourceID;
        if (dataSourceID.Length != 0)
        {
            Control control = DataBoundControlHelper.FindControl(this, dataSourceID);
            if (control == null)
            {
                throw new HttpException(SR.GetString("DataControl_DataSourceDoesntExist", new object[] { this.ID, dataSourceID }));
            }
            source = control as IDataSource;
            if (source == null)
            {
                throw new HttpException(SR.GetString("DataControl_DataSourceIDMustBeDataControl", new object[] { this.ID, dataSourceID }));
            }
        }
        return source;
    }

    protected override void LoadViewState(object savedState)
    {
        if (this.IsUsingModelBinders)
        {
            Pair pair = (Pair) savedState;
            if (savedState == null)
            {
                base.LoadViewState(null);
            }
            else
            {
                base.LoadViewState(pair.First);
                if (pair.Second != null)
                {
                    ((IStateManager) this.ModelDataSource).LoadViewState(pair.Second);
                }
            }
        }
        else
        {
            base.LoadViewState(savedState);
        }
    }

    protected void MarkAsDataBound()
    {
        this.ViewState["_!DataBound"] = true;
    }

    protected virtual void OnCreatingModelDataSource(CreatingModelDataSourceEventArgs e)
    {
        CreatingModelDataSourceEventHandler handler = base.Events[EventCreatingModelDataSource] as CreatingModelDataSourceEventHandler;
        if (handler != null)
        {
            handler(this, e);
        }
    }

    protected override void OnDataPropertyChanged()
    {
        this._currentViewValid = false;
        this._currentDataSourceValid = false;
        base.OnDataPropertyChanged();
    }

    protected virtual void OnDataSourceViewChanged(object sender, EventArgs e)
    {
        if (!this._ignoreDataSourceViewChanged)
        {
            base.RequiresDataBinding = true;
        }
    }

    private void OnDataSourceViewSelectCallback(IEnumerable data)
    {
        this._ignoreDataSourceViewChanged = false;
        if (base.IsDataBindingAutomatic)
        {
            this.OnDataBinding(EventArgs.Empty);
        }
        if (base.AdapterInternal != null)
        {
            DataBoundControlAdapter adapterInternal = base.AdapterInternal as DataBoundControlAdapter;
            if (adapterInternal != null)
            {
                adapterInternal.PerformDataBinding(data);
            }
            else
            {
                this.PerformDataBinding(data);
            }
        }
        else
        {
            this.PerformDataBinding(data);
        }
        this.OnDataBound(EventArgs.Empty);
    }

    protected internal override void OnLoad(EventArgs e)
    {
        base.ConfirmInitState();
        this.ConnectToDataSourceView();
        if (((this.Page != null) && !this._pagePreLoadFired) && (this.ViewState["_!DataBound"] == null))
        {
            if (!this.Page.IsPostBack)
            {
                base.RequiresDataBinding = true;
            }
            else if (base.IsViewStateEnabled)
            {
                base.RequiresDataBinding = true;
            }
        }
        base.OnLoad(e);
    }

    protected override void OnPagePreLoad(object sender, EventArgs e)
    {
        base.OnPagePreLoad(sender, e);
        if (this.Page != null)
        {
            if (!this.Page.IsPostBack)
            {
                base.RequiresDataBinding = true;
            }
            else if (base.IsViewStateEnabled && (this.ViewState["_!DataBound"] == null))
            {
                base.RequiresDataBinding = true;
            }
        }
        this._pagePreLoadFired = true;
    }

    protected internal virtual void PerformDataBinding(IEnumerable data)
    {
    }

    protected override void PerformSelect()
    {
        if (!base.IsDataBindingAutomatic)
        {
            this.OnDataBinding(EventArgs.Empty);
        }
        DataSourceView data = this.GetData();
        this._arguments = this.CreateDataSourceSelectArguments();
        this._ignoreDataSourceViewChanged = true;
        base.RequiresDataBinding = false;
        this.MarkAsDataBound();
        data.Select(this._arguments, new DataSourceViewSelectCallback(this.OnDataSourceViewSelectCallback));
    }

    protected override object SaveViewState()
    {
        object obj2 = base.SaveViewState();
        if (!this.IsUsingModelBinders)
        {
            return obj2;
        }
        Pair pair = new Pair {
            First = obj2,
            Second = ((IStateManager) this.ModelDataSource).SaveViewState()
        };
        if ((pair.First == null) && (pair.Second == null))
        {
            return null;
        }
        return pair;
    }

    protected override void TrackViewState()
    {
        base.TrackViewState();
        if (this.IsUsingModelBinders)
        {
            ((IStateManager) this.ModelDataSource).TrackViewState();
        }
    }

    internal virtual void UpdateModelDataSourceProperties(ModelDataSource modelDataSource)
    {
        modelDataSource.UpdateProperties(this.ItemType, this.SelectMethod);
    }

    protected override void ValidateDataSource(object dataSource)
    {
        if (((dataSource != null) && !(dataSource is IListSource)) && (!(dataSource is IEnumerable) && !(dataSource is IDataSource)))
        {
            throw new InvalidOperationException(SR.GetString("DataBoundControl_InvalidDataSourceType"));
        }
    }

    // Properties
    [DefaultValue(""), Themeable(false), WebSysDescription("DataBoundControl_DataMember"), WebCategory("Data")]
    public virtual string DataMember
    {
        get
        {
            object obj2 = this.ViewState["DataMember"];
            if (obj2 != null)
            {
                return (string) obj2;
            }
            return string.Empty;
        }
        set
        {
            this.ViewState["DataMember"] = value;
            this.OnDataPropertyChanged();
        }
    }

    [IDReferenceProperty(typeof(DataSourceControl))]
    public override string DataSourceID
    {
        get
        {
            return base.DataSourceID;
        }
        set
        {
            base.DataSourceID = value;
        }
    }

    [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
    public IDataSource DataSourceObject
    {
        [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
        get
        {
            return this.GetDataSource();
        }
    }

    protected override bool IsUsingModelBinders
    {
        get
        {
            return !string.IsNullOrEmpty(this.SelectMethod);
        }
    }

    [WebCategory("Data"), WebSysDescription("DataBoundControl_ItemType"), DefaultValue(""), Themeable(false)]
    public virtual string ItemType
    {
        get
        {
            return (this._itemType ?? string.Empty);
        }
        set
        {
            if (!string.Equals(this._itemType, value, StringComparison.OrdinalIgnoreCase))
            {
                this._itemType = value;
                this.OnDataPropertyChanged();
            }
        }
    }

    private ModelDataSource ModelDataSource
    {
        get
        {
            if (this._modelDataSource == null)
            {
                this._modelDataSource = new ModelDataSource(this);
            }
            return this._modelDataSource;
        }
        set
        {
            if (value == null)
            {
                throw new ArgumentNullException("value");
            }
            this._modelDataSource = value;
        }
    }

    protected DataSourceSelectArguments SelectArguments
    {
        get
        {
            if (this._arguments == null)
            {
                this._arguments = this.CreateDataSourceSelectArguments();
            }
            return this._arguments;
        }
    }

    [DefaultValue(""), Themeable(false), WebCategory("Data"), WebSysDescription("DataBoundControl_SelectMethod")]
    public virtual string SelectMethod
    {
        get
        {
            return (this._selectMethod ?? string.Empty);
        }
        set
        {
            if (!string.Equals(this._selectMethod, value, StringComparison.OrdinalIgnoreCase))
            {
                this._selectMethod = value;
                this.OnDataPropertyChanged();
            }
        }
    }
}